Стабилизация перевёрнутого маятника с подвижной осью подвеса

Расчётно-графическая работа для лабораторного практикума. Вспомогательные и дополнительные материалы

Автор: В. А. Костин
2021 год $\newcommand{\ctg}{\mathop{\mathrm{ctg}}\nolimits}$ $\newcommand{\tg}{\mathop{\mathrm{tg}}\nolimits}$ $\newcommand{\arctg}{\mathop{\mathrm{arctg}}\nolimits}$ $\newcommand{\degree}{^{\circ}}$ $\renewcommand{\Re}{\mathop{\mathrm{Re}}\nolimits}$

Приложение 1. Введение в конструкции языка Python

Функция print и вывод ячеек

При настройках блокнота по умолчанию текстовое представление выходного результата последней команды (кроме инструкций присвоения) в ячейке печатается в вывод ячейки (cell output). Настройки может быть изменены установкой значения InteractiveShell.ast_node_interactivity, InteractiveShell определён в модуле IPython.core.interactiveshell. Возможные значения InteractiveShell.ast_node_interactivity: 'all', 'last', 'last_expr' (по умолчанию), 'none', 'last_expr_or_assign'.

Точка с запятой подавляет печать выходного результата последней инструкции.

В Python 3 функция print в Python 3 по умолчанию выводит в стандартный вывод объекты, являющиеся её начальными неименованными аргументами. Стандартный вывод интерпретатора для инструкций в некоторой ячейке с кодом (code cell) в блокноте Jupyter печатается непосредственно после этой ячейки.

Форматный вывод может осуществляться с помощью метода format переменных и литералов строкового типа.

Арифметические операции

Базовые арифметические операции, в целом обозначаются так же, как и в большинстве языков. Круглые скобки могут быть использованы для группировки действий. В частности, сложение выполняется с помощью оператора +.

Вычитание выполняется с помощью оператора -.

Умножение выполняется с помощью оператора *.

Вещественное деление выполняется с помощью оператора /. Результат вещественного деления — всегда число с плавающей точкой.

Целочисленное деление выполняется с помощью оператора //. Результат — целое число, не превышающее вещественное частное.

Остаток от деления может быть получен с помощью оператора %.

Оператор ** позволяет выполнять возведение в степень.

Для всех операторов, перечисленных выше, имеются варианты с присвоением: +=, -=, *=. /=, //=. %=, **=.

Имеется встроенная поддержка комплексной арифметики.

Типизация

Python — язык с динамической типизацией и развитой системой преобразований типов по умолчанию. Тип переменной может быть определён с помощью встроенной функции type.

Python — строго типизованный язык.

Операторы контроля потока выполнения

Python предлагает традиционный набор операторов для контроля потока выполнения. Среди них условный оператор if. Альтернативный блок указывается после оператора else. В случае нескольких условий и альтернатив может быть использован оператор elif. Имеется традиционный набор операторов сравнения ==, <, >, <=, >=, !=.

Циклы могут быть организованы с помощью операторов while и for. Внутри цикла могут быть использованы операторы break (для прерывания цикла) и continue (для перехода к следующей итерации).

Оператор цикла for используется в паре с оператором in, после которого указывается итерируемый объект (iterable). В качестве такого объекта могут выступать списки, кортежи и словари, а также некоторые другие объекты. Для итерации по арифметической прогрессии может быть использован итератор, конструируемый функцией range. Если range используется с одним целочисленным аргументом, например, range(stop), то итерация проводится от нуля последовательно (через единицу) до stop - 1. Если аргументов 2, range(start, stop), то итерация проводится от start до stop - 1. Третий аргумент может быть использован, для того чтобы указать шаг арифметической прогрессии.

Функции могут быть определены с помощью оператора def. Возвращаемый результат может быть указан с помощью оператора return. Функция может возращать несколько значений (то есть возращать кортеж значений).

Короткие функции могут быть определены с помощью оператора lambda.

Кортежи и списки

Python обладает несколькими встроенными типа составных объектов. В частности, такими типами являются списки и кортежи (неизменяемые списки). Списки конструируются из элементов с помощью квадратных скобок [], кортежи — с помощью круглых ().

Удобным методом создания списков и кортежей является списковое включение (list comprehension), осуществляемое с помощью операторов квадратных скобок и операторов for и in.

Обращение к элементу осуществляется посредством оператора квадратных скобок [].

Списки и кортежи в Python поддерживают срезы (slicing), то есть обращение к подсписку или подкортежу, заданному арифметической прогрессией индексов.

Изменяемые и неизменяемые объекты. Сущность присваиваиния в Python

Любой объект в Python может быть изменяемым (mutable) или неизменяемым (immutable). Числа и строки — примеры неизменяемых объектов. Неизменяемыми являются объекты числовых типов, булевы значения, строки, неизменяемые последовательности байтов (тип bytes), кортежи (тип tuple), неизменяемые (замороженные) множества (тип frozenset). Остальные объекты, например, списки, являются изменяемыми объектами. Присваивание переменной изменяемого или неизменяемого объекта носит различный характер.

Приложение 2. Примеры использования библиотеки Numpy

Подключение библиотеки

При работе с Python в неинтерактивном режиме для библиотеки Numpy рекомедуется использовать стандартную инструкцию импорта import numpy или для сокращения import numpy as np и обращаться к фукнциям и классам библиотеки через модуль, например, numpy.arange или np.arange. При интерактивной работе, например, в Jupyter, для подключения объектов Numpy и Matplotlib удобно воспользоваться модулем pylab и импортировать все объекты в глобальное пространство имён. При этом функции и классы оказываются доступны без указания библиотеки, то есть используется arange вместо numpy.arange.

Многомерные массивы

Библиотека вводит новый тип составного объекта — numpy.ndarray. Этот тип позволяет хранить и проводить операции с многомерными массивами однородных (то есть однотипных) данных. Функция array позволяет создать такой массив из других составных объектов, например, из простых и вложенных списков или кортежей.

Тип элемента массива содержится в поле dtype.

Поле ndim содержит число измерений массива.

Поле size содержит число элементов массива.

Поле shape содержит кортеж с размерами массива вдоль различных измерений

Доступ к отдельному элементу может быть осуществлён посредством оператора квадратных скобок [].

Создание специальных массивов

Массив содержащий арифметическую прогрессию может быть создан с помощью функции arange. Смысл первых трёх аргументов функции аналогичен смыслу аргументов функции range, но в качестве аргументов могут выступать не только целые числа, но и числа с плавающей точкой.

Функция linspace также как функция arange выдаёт массив, содержащий арифметическую прогрессию, но принимает в качестве аргументов начальное значение, конечное значение и размер выходного массива.

Функция meshgrid конструирует координатные матрицы из координатных векторов.

Функция zeros создаёт массив заданных формы и типа, заполненный нулями.

Функция full создаёт массив с одинаковыми значениями всех элементов.

Функция empty создаёт пустой массив (то есть при его создания память не перезаписывается какими-либо заданными значениями).

Функции zeros_like, full_like и empty_like действуют как функции zeros, full и empty, но принимают в качестве аргумента вместо формы другой массив у которого копирует форму и тип (если тот не указывается явно среди аргументов).

Так как массивы Numpy являются изменяемыми объектами, присваивание не создаёт копии массива. Для создания копии массива используется функция copy.

Поэлементные операции

Для массивов Numpy переопределены арифметические операции и элементарные математические функции. В большистве случаев операции и функции применяются поэлементно. При этом для бинарных операций оба операнда должны иметь одинаковую форму либо один из операндов должен быть скаляром. При выполнении операций тип элемента массива может меняться (например, при делении целочисленных массивов чисел или вычислении трансцендентых функций от таких массивов).

Срезы

Массивы Numpy поддерживают срезы (слайсинг) для операций с подмассивами.

Для положительных c срез a:b:c выбирает каждый c-й элемент с номерами ниже b, начиная с элемента номером a, при этом значения a и b берутся по модулю размера массива в соответствующем измерении.

Для отрицательных c срез a:b:c выбирает каждый c-й элемент в обратном порядке с номерами выше b, начиная с элемента номером a.

Каждое из числе a, b, c в срезе a:b:c может быть опущено. Значение a и c по умолчанию равны 0 и 1 соответственно, значение b по умолчанию равно размеру массива по соответствующему измерению. Двоеточие в конце среза также может опускаться.

Одиночное двоеточие обозначает все элементы в каком-то измерении. Его удобно использовать, чтобы выбирать проекции многомерного массива, например, выбирать некоторые столбцы в двумерном массиве (матрице).

При аналогичном выборе строк в матрице запятую с двоеточием в конце можно опустить.

Приложение 3. Примеры использования библиотеки Matplotlib

Подключение и настройка библиотеки

Библиотека Matplotlib предлагает два подхода к построению рисунков императивный (схожий с Matlab) и объектно-ориентированный. Для простой графики, по всей видимости, более удобен императивный подход, реализуемый с помощью функций модуля matplotlib.pyplot. При работе с Python в неинтерактивном режиме для его подключения рекомедуется использовать стандартную инструкцию импорта import matplotlib.pyplot as plt и обращаться к фукнциям и классам библиотеки через модуль, например, plt.plot. При интерактивной работе, например, в Jupyter, для подключения объектов Numpy и Matplotlib удобно воспользоваться модулем pylab и импортировать все объекты в глобальное пространство имён. При этом функции и классы оказываются доступны без указания библиотеки, то есть используется plot вместо plt.plot.

Так называемая «магическая» команда %matplotlib позволяет выбрать тип вывода (бэкенд) рисунков. Параметр inline указывает на то, что рисунки Matplotlib должны быть встроены как растровые изображения, для интерактивных рисунков на JavaScript можно использовать параметр notebook вместо inline. Команда %matplotlib --list выводит список возможных типов вывода (бэкендов).

Переменная rcParams содержит различные настройки рисунков. Доступ к настройкам осуществляется по ключам. Например, ключи figure.figsize и figure.dpi соответствуют размеру рисунков по умолчанию в дюймах и разрешению рисунков в точках на дюйм.

Построение графика функции

Один из наиболее простых способов построить график функции или параметрически заданную кривую в Matplotlib — использовать функцию plot. Функция принимает в качестве аргумента массивы абсцисс и ординат точек кривой. Рисунок можно снабдить заголовком с помощью функции title, а подписать оси можно с помощью функций xlabel и ylabel. Добавить подпись в произвольном месте можно с помощью команды text. Подписи могут содержать формулы в формате, схожем с LaTeX.

Функция plot также может принимать аргументы, контролирующие параметры отображения кривой.

Третьим аргументов функция plot может принимать стилевую строку, указывающую цвет кривой, её тип и вид маркеров.

Функция plot может несколько наборов абсцисс, ординат и стилевых строк для построения нескольких графиков в одних осях.

Несколько графиков можно построить, вызвав функцию plot несколько раз.

Функция fill аналогична функции plot, но вместо графика или точек рисует внутреннюю область графика, заполненную цветом. В примере ниже инструкция axis('equal') устанавливает одинаковые масштабы по горизонтальной и вертикальной осям.

Построение нескольких координатных плоскостей (осевых коробок) на одном рисунке

Несколько координатных плоскостей (осей, осевых коробок, axes) на одном рисунке можно получить с помощью функции subplot. Команда subplot(nrows, ncols, index) создаёт виртуальную сетку из координатных плоскостей с nrows строками и ncols столбцами и возвращает координатную плоскость с индексом index из этой сетки. Общий заголовок для всех координатных плоскостей можно получить с помощью функции suptitle. Функция tight_layout может использовать для корректировки размеров осей тем, чтобы подписи по осям не перекрывали других подрисунков и не выходили за пределы всего рисунка. Аргумент rect указывает на положение граничной рамки, содержащей все подрисунки, но не главный заголовок.

Построение фазового портрета

Функцию streamplot удобно использовать для построения фазовых портретов, силовых линий векторных полей или линий тока на плоскости. В простейшем варианте функция принимает четыре аргумента: первые два задают координатные матрицы, два следующих задают две компоненты векторного поля. Одним из возможных дополнительных параметров является density, определяющий характерную плотность отображаемых линий (то есть обратное расстояние между линиями). Далее приводится пример построения фазовой портрета с использованием функции streamplot для системы $\ddot\varphi + 0.3\dot\varphi + \sin\varphi = 0$.

Построение контурной карты

Линии уровня некоторой функции двух переменных можно построить с помощью функции contour. В одном из вариантов функция принимает первыми аргументами две координатные матрицы и матрицу значений функции. Четвёртый аргумент может задать количество линий уровня или упорядоченный по возрастанию набор значений фукнции для которых строятся линии уровня. Функция clabel может быть использована для расстановки меток значений уровня на линиях. В этой функции параметр inline контролирует, стираются ли линии уровня под метками, параметр fontsize управляет размером шрифта меток. Рисунок также можно снабдить шкалой с помощью функции colorbar.

Функция contourf работает аналогично contour но строит не сами линии уровня, а закрашивает разными цветами области между линиями уровня. Такой рисунок также можно снабдить шкалой с помощью функции colorbar.

Построение тепловой карты

Упомянутой выше в разделе 5.3.5 функции contourf может использоваться для построения векторной тепловой карты, представляющей набор областей равных цветов. Для построения растровой тепловой карты можно применять функцию imshow. В этой функции параметр origin указывает, верхнему или нижнему левому углу панели соответствует первый (с индексами 0, 0) элемент изображаемого массива. Обычно этот параметр должен быть установлен в 'lower' при построении тепловых карт функций, заданных матрицами в традиционных декартовых координатах. Параметр extent указывает координаты левого нижнего и правого верхнего углов тепловой карты.

Приложение 4. Справка по функциям модуля control_theory

Plant

class Plant(seed_value=0)

Класс Plant — является базовым интерфейсным классом для представления объекта управления, задаваемого с помощью системы обыкновенных дифференциальных уравнений $$\dot{\mathbf x} = \mathbf f(\mathbf x, \mathbf u, t),$$ где $\mathbf x$ — векторная переменная, определяющеая состояние объекта (элемент пространства состояний), $\mathbf u$ — векторное управление, функция $\mathbf f$ полностью определяет модель объекта управления.

Экземпляр базового класса Plant представляет пустой (тривиальный) объект управления без переменных, параметров и управления. Экземпляры классов-наследников представляют специфичные нетривиальные объекты управления.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
seed_value int Зерно генератора случайных чисел для инициализации параметров объекта управления (если такие параметры есть). 0

Plant.PLANT_DIM, Plant.CONTROL_DIM, Plant.OTYPE

Класс и его наследники содержит следующие поля класса (то есть поля, общие для всех экземпляров класса).

Название Тип Описание
PLANT_DIM int Размерность состояния объекта (то есть вектора $\mathbf x$).
CONTROL_DIM int Размерность управления (то есть вектора $\mathbf u$).
OTYPE str Название (строковый идентификатор) типа объекта управления.

Plant.__call__

f = Plant.__call__(x, u=zeros(CONTROL_DIM), t=0.)

Экзмепляр класса является функтором и при вызове вычисляет значение временной производной $\dot {\mathbf x}$, иными словами вычисляет функцию $\mathbf f$.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
x array_like, shape=(PLANT_DIM,) Вектор состояния объекта $\mathbf x$.
u array_like, shape=(CONTROL_DIM,) Вектор управления $\mathbf u$ (по умолчанию — нулевой). zeros(CONTROL_DIM)
t number Значение времени $t$. 0.

Возвращаемые значения

Название Тип Описание
f ndarray, shape=(PLANT_DIM,), dtype='double' Вектор временной производной $\mathbf f(\mathbf x, \mathbf u, t)$ состояния объекта.

Plant.__str__

plant_str = Plant.__str__()

Для экзмепляра класса определена функция преобразования в строку __str__.

Возвращаемые значения

Название Тип Описание
plant_str str Строковое представление экземпляра класса.

Pendulum

Класс Pendulum — потомок класса Plant для представления маятника на каретке, описываемого системой $(8)$.

Pendulum.omega, Pendulum.alpha, Pendulum.lambd, Pendulum.mu, Pendulum.nu

Экземпляр класса содержит следующие поля, соответствующие параметрам системы $(8)$. При инициализации объекта связываются со случайными действительными числами.

Название Тип Описание
omega float Параметр $\Omega$, значение при инициализации равномерно распределено в $[0.3, 1.8)$.
alpha float Параметр $\alpha$, значение при инициализации равномерно распределено в $[0.3, 0.8)$.
lambd float Параметр $\lambda$, значение lambd - nu при инициализации равномерно распределено в $[0.01, 0.11)$.
mu float Параметр $\mu$, значение mu - alpha * nu при инициализации равномерно распределено в $[0.01, 0.11)$.
nu float Параметр $\nu$, значение при инициализации равномерно распределено в $[0.01, 0.11)$.

Control

class Control()

Класс Control — является базовым интерфейсным классом для представления стратегии управления, задаваемой с помощью системы уравнений $$\mathbf u = \mathbf g(\mathbf x, \mathbf v, t),$$ $$\dot{\mathbf v} = \mathbf h(\mathbf x, \mathbf v, t),$$ где $\mathbf x$ — векторная переменная, определяющеая состояние объекта (элемент пространства состояний), $\mathbf u$ — векторное управление, $\mathbf v$ — внутренние («скрытые») переменные, характеризующие состояние регулятора, функция $\mathbf h$ определяет внутреннюю динамику скрытых переменных регулятора, функция $\mathbf g$ связывает управление со состояниями объекта управления и регулятора.

Экземпляр базового класса Control представляет пустой регулятор без переменных. Экземпляры классов-наследников представляют специфичные нетривиальные регуляторы.

Control.PLANT_DIM, Control.CONTROL_DIM, Control.HIDDEN_DIM, Control.CTYPE

Класс и его наследники содержит следующие поля класса (то есть поля, общие для всех экзмепляров класса).

Название Тип Описание
PLANT_DIM int Размерность состояния объекта (то есть вектора $\mathbf x$).
CONTROL_DIM int Размерность управления (то есть вектора $\mathbf u$).
HIDDEN_DIM int Размерность состояния регулятора (то есть вектора $\mathbf v$).
CTYPE str Название (строковый идентификатор) типа регулятора.

Control.__call__

g = Control.__call__(x, v, t=0.)

Экзмепляр класса является функтором и при вызове вычисляет значение временной производной $\dot {\mathbf v}$, иными словами вычисляет функцию $\mathbf h$.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
x array_like, shape=(PLANT_DIM,) Вектор состояния объекта $\mathbf x$.
v array_like, shape=(HIDDEN_DIM,) Вектор состояния регулятора $\mathbf v$.
t number Значение времени $t$. 0.

Возвращаемые значения

Название Тип Описание
g ndarray, shape=(HIDDEN_DIM,), dtype='double' Вектор временной производной $\mathbf h(\mathbf x, \mathbf v, t)$ состояния регулятора.

Control.control

u = Control.control(x, v, t=0.)

Метод control вычисляет управление $\mathbf u$ по состояниям объекта и регулятора, иными словами вычисляет функцию $\mathbf g$.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
x array_like, shape=(PLANT_DIM,) Вектор состояния объекта $\mathbf x$.
v array_like, shape=(HIDDEN_DIM,) Вектор состояния регулятора $\mathbf v$.
t number Значение времени $t$. 0.

Возвращаемые значения

Название Тип Описание
u ndarray, shape=(CONTROL_DIM,), dtype='double' Вектор управления $\mathbf u$.

Control.__str__

control_str = Control.__str__()

Для экзмепляра класса определена функция преобразования в строку __str__.

Возвращаемые значения

Название Тип Описание
control_str str Строковое представление экземпляра класса.

ZeroControl

class ZeroPendulumControl(plant_dim, control_dim)

Класс ZeroPendulumControl — потомок класса Control для представления нулевого управления для маятником на тележке Pendulum.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
plant_dim int Размерность состояния объекта управления. 1
control_dim int Размерность управления. 1

StateFeedbackControl

class StateFeedbackControl(plant_dim, control_dim, fun)

Класс StateFeedbackControl — потомок класса ZeroControl для представления управления по состоянию объекта.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
plant_dim int Размерность состояния объекта управления. 1
control_dim int Размерность управления. 1
fun u = callable(x); x: arraylike, shape=(plant_dim,); u: arraylike, (control_dim,) или None Функция, задающая стратегию управления: принимает текущее состояние объекта x и возращает управление u. Если передаётся None, то функция считается возвращающей нулевой вектор (поведение класса не отличается от ZeroControl). None

StateFeedbackControl.fun

Экземпляр класса содержит поле с функцией, задающей стратегию управления.

Название Тип Описание
fun u = callable(x); x: arraylike, shape=(PLANT_DIM,); u: arraylike, (CONTROL_DIM,) Функция, задающая стратегию управления: принимает текущее состояние объекта x и возращает управление u.

StateTimeFeedbackControl

class StateTimeFeedbackControl(plant_dim, control_dim, fun)

Класс StateFeedbackControl — потомок класса ZeroControl для представления комбинированного управления по состоянию объекта и моменту времени (программного управления).

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
plant_dim int Размерность состояния объекта управления. 1
control_dim int Размерность управления. 1
fun u = callable(x, t); x: arraylike, shape=(plant_dim,); t: number; u: arraylike, (control_dim,) или None Функция, задающая стратегию управления: принимает текущее состояние объекта x и время t и возращает управление u. Если передаётся None, то функция считается возвращающей нулевой вектор (поведение класса не отличается от ZeroControl). None

StateTimeFeedbackControl.fun

Экземпляр класса содержит поле с функцией, задающей стратегию управления.

Название Тип Описание
fun u = callable(x, t); x: arraylike, shape=(PLANT_DIM,); t: number; u: arraylike, (CONTROL_DIM,) Функция, задающая стратегию управления: принимает текущее состояние объекта x и время t и возращает управление u.

LinearStateControl

class LinearStateControl(plant_dim, control_dim, k=None)

Класс LinearStateControl — потомок класса ZeroControl для представления линейного управления по состоянию.

Принимаемые аргументы

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
plant_dim int Размерность состояния объекта управления. 1
control_dim int Размерность управления. 1
k arraylike, shape=(control_dim, plant_dim) или shape=(plant_dim,), если control_dim равно 1, или None Матрица или вектор $\mathbf k$ коэффициентов линейного закона управления. Задание None эквивалентно заданию нулевой матрицы с shape=(control_dim, plant_dim). None

LinearStateControl.k

Экземпляр класса содержит поле с матрицей $\mathbf k$ коэффициентов линейного закона управления.

Название Тип Описание
k ndarray, shape=(CONTROL_DIM, PLANT_DIM), dtype='double' Матрица коэффциентов $\mathbf k$ линейного закона управления (матрица умножается на вектор слева).

LinearSinPendulumControl

class LinearSinPendulumControl(k=zeros(4, dtype='double'))

Класс LinearSinPendulumControl — потомок класса Control для представления управления $u = k_0 \sin(x_0) + k_1 x_1 + k_2 x_2 + k_3 x_3$ для маятника на каретке.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
k array_like, shape=(4,) Вектор $\mathbf k$ коэффициентов линейного закона управления. zeros(4, dtype='double')

LinearSinPendulumControl.k

Экземпляр класса содержит поле с вектором $\mathbf k$ коэффициентов линейного закона управления.

Название Тип Описание
k ndarray, shape=(4,), dtype='double' Вектор коэффциентов $\mathbf k$.

rk

tout, y = rk(rhs, y0, t, N=1, stop_condition=None)

Функция rk реализует классический метод Рунге — Кутты четвёртого порядка для решения обыкновенных дифферециальных уравений.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
rhs dydt1 = callable(y1, t1); y1: ndarray, dtype=float or dtype=complex; t1: number; dydt1: ndarray, shape=y1.shape Функция, задающая систему обыкновенных уравнений: для массива y1 значений зависимых переменных (координат) и независимой переменной (времени) t1 возвращает массив dydt1 значений производных координат по времени.
y0 arraylike, shape=y1.shape Массив начальных значений координат.
t arraylike, ndim=1 Сортированный по возрастанию или убыванию массив значений времени, для которых вычисляются значения координат. Первый элемент массива отвечает времени для которого задаётся начальное значение. Если массив сортирован по убыванию, расчёт ведётся в обратном времени (то есть в сторону уменьшения времени).
N int Число шагов метода Рунге — Кутты, приходящееся на один интервал, образуемый соседними элементами из t. 1
stop_condition None или stop_flag = callable(y1, t1); y1: ndarray, dtype=float or dtype=complex; t1: number; stop_flag: bool Функция, задающая критерий остановки, если для текущих значений y1 и t1 выдаёт True, выполнение останавливается и выдаются предшествующие рассчитанные значения времени и переменного вектора. Если задано None выполнение останавливается, когда пройден весь массив времён t. None

Возращаемые значения

Название Тип Описание
tout ndarray, ndim=y1.ndim + 1, ndim=1, shape[0] <= t.shape[0] Массив, содержащий значения времён, для которых были рассчитаны значения координат. Если функция stop_condition не задана или не выдавала True в ходе расчёта, выводится копия t. Иначе выводится обрезанный вариант массива t, при этом последний элемент массива отвечает времени, на котором условие остановки было выполнено.
y ndarray, ndim=y1.ndim + 1, shape=(tout.shape[0],) + y1.shape Многомерный массив, содержащий рассчитанные значения координат для времён из tout.

pcrhs

rhs = pcrhs(p, c)

Функция pcrhs для заданных объекта и регулятора создаёт функцию (функциональный объект), которая рассчитывает правую часть системы обыкновенных дифференциальных уравнений, описывающих совместную эволюцию состояний объекта и регулятора во времени $$\dot{\mathbf X} = \mathbf F(\mathbf X, t),$$ где $\mathbf X = \begin{bmatrix} \mathbf x \\ \mathbf v\end{bmatrix}$ — объединённый вектор состояний объекта и регулятора, $\mathbf F(\mathbf X, t) = \begin{bmatrix} \mathbf f[\mathbf x, \mathbf g(\mathbf x, \mathbf v, t), t] \\ \mathbf h(\mathbf x, \mathbf v, t) \end{bmatrix}$. Эта система эквивалентна системе приведённых ранее уравнений $$\dot{\mathbf x} = \mathbf f(\mathbf x, \mathbf u, t),$$ $$\mathbf u = \mathbf g(\mathbf x, \mathbf v, t),$$ $$\dot{\mathbf v} = \mathbf h(\mathbf x, \mathbf v, t).$$

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
p Plant Объект управления.
c Control, PLANT_DIM=p.PLANT_DIM, CONTROL_DIM=p.CONTROL_DIM Регулятор.

Возращаемые значения

Название Тип Описание
rhs dydt1 = callable(y1, t1); y1: ndarray, dtype=float or dtype=complex, shape=(p.PLANT_DIM + c.HIDDEN_DIM,); t1: number; dydt1: ndarray, shape=y1.shape Функция, вычисляющая зависимость $\mathbf F(\mathbf X, t)$.

control_output

ufun = control_output(c)

Функция control для заданного регулятора создаёт функцию (функциональный объект), которая рассчитывает управление по состояниям объекта и управления, $\mathbf u(\mathbf X, t) = \mathbf g(\mathbf x, \mathbf v, t)$.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
c Control, PLANT_DIM=p.PLANT_DIM, CONTROL_DIM=p.CONTROL_DIM Регулятор.

Возращаемые значения

Название Тип Описание
ufun u = callable(y1, t1); y1: ndarray, dtype=float or dtype=complex, shape=(c.PLANT_DIM + c.HIDDEN_DIM,); t1: number; u: ndarray, shape=(c.CONTROL_DIM,) Функция, вычисляющая зависимость $\mathbf u(\mathbf X, t)$.

integrate

t, y = integrate(p, c, x0, v0, dt, T, N=1, method=rk, return_control=False, stop_condition=None)

или

t, y, u = integrate(p, c, x0, v0, dt, T, N=1, method=rk, return_control=False, stop_condition=None)

Функция integrate для заданных объекта и регулятора рассчитывает эволюцию их состояний во времени посредством численного интегрирования соответствующих обыкновенных дифференциальных уравнений.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
p Plant Объект управления.
c Control, PLANT_DIM=p.PLANT_DIM, CONTROL_DIM=p.CONTROL_DIM Регулятор.
x0 array_like, shape=(p.PLANT_DIM,) Начальное состояние объекта.
v0 array_like, shape=(c.HIDDEN_DIM,) Начальное состояние регулятора.
dt number Шаг по времени в выходных массивах. Если задаётся отрицательным, то расчёт ведётся в обратном времени.
T number Максимальное (для положительного dt) или минимальное (для отрицательного dt) время, до которого рассчитывается эволюция.
N int Число шагов метода интегрирования, приходящееся на один шаг по времени в выходных массивах. 1
method callable Функция, реализующая метод интегрирования с сигнатурой, как у rk. rk
return_control Если True, то возвращает массив значений управления помимо массивов времени и состояний. False
stop_condition None or b1 = callable(y1, t1); y1: ndarray, shape=(p.PLANT_DIM + c.HIDDEN_DIM,); t1: number; b1: bool Необязательная функция координат и времени, задающая условие остановки расчёта, если функция возвращает True после шага, расчёт останавливается. None

Возращаемые значения

Название Тип Описание
t ndarray, ndim=1 Эквидистантный массив значений времени, для которых выводятся состояния объекта и регулятора. Если функция stop_condition не задана или не сработала в ходе расчёта, то форма выходного массива shape=(int(ceil(T/dt)),). Если функция stop_condition сработала, то последний элемент массива отвечает времени, на котором условие остановки было выполнено.
y ndarray, shape=(t.shape[0], p.PLANT_DIM + c.HIDDEN_DIM) Двумерный массив, содержащий рассчитанные значения состояний объекта и регулятора для времён из t. Состояния объекта содержатся в первых p.PLANT_DIM столбцах. В оставшихся c.HIDDEN_DIM столбцах содержатся состояния регулятора.
u ndarray, shape=(t.shape[0], p.CONTROL_DIM) Двумерный массив, содержащий рассчитанные значения управления для времён из t. Возвращается, если return_control задано как True.

animate_pendulum

anim = animate_pendulum(t, y, xlim='auto', ylim=(-1.2, 1.2), resolution=(960, 540), dpi=108, spacing=1, invsec=1.0, filename=None, codec=None, progress=True)

Функция animate_pendulum строит объект-анимацию matplotlib.animation.Animation по заданным состояниям маятника на эквидистантной временной сетке. Длина маятника полагается равной 1.

Принимаемые аргументы

Название Тип Описание Значение по умолчанию
t ndarray, ndim=1 Сортированный по возрастанию эквидистантный массив значений времени, для которых задаются состояния маятника.
y ndarray, ndim=2, shape[0]=t.shape[0], shape[1]>=3 Двумерный массив, содержащий состояния маятника для времён из t. По первому измерению меняется время, по второму — номер переменной, фактически используются только первый и третий столбцы, в которых содержатся значения угла $\varphi$ и положения каретки $\xi$ соответственно.
xlim 'auto' or 'center' or arraylike, shape=(2,) Интервал изменения горизонтальной координаты в анимации. Если xlim задано как 'auto' выбирается автоматически, в соответствии с заданным разрешением кадра и диапазоном движения каретки. Если xlim задано как 'center' выбирается автоматически, в соответствии с разрешением кадра, так что бы середина интервала совпдала с начальным положением каретки. 'auto'
ylim arraylike, shape=(2,) Интервал изменения вертикальной координаты в анимации. (-1.2, 1.2)
resolution arraylike, shape=(2,) Разрешение кадра. (960, 540)
dpi number Число пикселей на дюйм (влияет на толщину линий и размер символов). 100
spacing int Количество шагов временной сетки t на один кадр анимации. 1
invsec number Продолжительность единицы времени (в которой задана сетка t) в секундах. 1.0
filename str or None Имя файла, в который записывается видео анимации, например 'test.mp4'. Если filename задано как None, запись в файл не производится. None
codec str or None Кодировщик видео, например 'h264'. Если задано как None используется кодировщик по умолчанию. None
progress bool Если задано как True, при сохранение в файл показывается индикатор прогресса. True

Возращаемые значения

Название Тип Описание
anim matplotlib.animation.Animation Анимированный объект matplotlib.

Приложение 5. Вспомогательные примеры к работе

Инициализация демонстрационного маятника

Пример расчёта временной эволюции демонстрационного маятника с нулевым управлением

Пример построения графика зависимости угла поворота маятника от времени
Пример построения временных зависимостей угла поворота и нормированного смещения каретки на одном рисунке
Пример построения траектории груза
Пример построения анимации движения маятника с выводом в блокнот и видео-файл

В качестве альтернативы можно выводить видео из предварительно созданного файла в ячейках Markdown. В таком случае видео будет отображаться и после перезагрузки страницы. Видео ниже вставлено с помощью команды

<video controls frameborder="0" allowfullscreen autoplay src="test.mp4" type=video/mp4></video>

Пример использования функции integrate для расчёта эволюции демонстрационного маятника с управлением по углу

Пример построения границы области притяжения положения равновесия $(0, 0)$ системы $\dot x = y$, $\dot y = -x - y + x^3$

В системе $\dot x = y$, $\dot y = -x - y + x^3$ имеется две седловые точки $(x, y) = (\pm 1, 0)$. Система симметрична относительно замены $(x, y) \rightarrow (-x, -y)$, и можно рассмотреть только седло $(x, y) = (1, 0)$ и две его устойчивые сепаратрисы. Вблизи этого седла система линеаризуется как $\dot x = y$, $\dot y = (x - 1) - y$ или $$\frac{d}{dt} \begin{bmatrix} x - 1 \\ y \end{bmatrix} = \begin{bmatrix} 0 & 1 \\ 1 & -1 \end{bmatrix} \begin{bmatrix} x - 1 \\ y \end{bmatrix}.$$ Матрица системы имеет собственные значения $\dfrac{-1 \pm \sqrt{5}}{2}$ и собственные векторы $\begin{bmatrix} 1 \\ \frac{-1 \pm \sqrt{5}}{2} \end{bmatrix}$. Устойчивым сепаратрисам отвечает отрицательное собственное число (нижний знак). Таким образом, в качестве начальных условий для нахождения сепаратрис можно взять $$ \begin{bmatrix} x(0) - 1 \\ y(0) \end{bmatrix} = \pm\delta \begin{bmatrix} 1 \\ \frac{1 - \sqrt{5}}{2} \end{bmatrix}, $$ где $\delta$ — некоторое достаточное малое (в масштабах нелинейности системы, то есть единицы) положительное число.

Пример построения D-разбиения для характеристического полинома $Q(p)$ уравнения $(9)$ с условием $\Re p < 0$

Характеристический полином уравнения  $(9)$ имеет вид $Q(p) = (1 - \alpha) p^2 + (\lambda + k_1) p - \Omega^2 + k_0$. Параметризуя границу интересующей области как $p = i\omega$, получаем систему уравнений $$k_0 - \Omega^2 - (1 - \alpha) \omega^2 = 0,$$ $$\omega k_1 + \omega \lambda = 0.$$ Уравнение особой прямой при $\omega = 0$ имеет вид $$k_0 - \Omega^2 = 0.$$ Решение системы при $\omega \neq 0$ имеет вид $$k_0 = \omega^2 (1 - \alpha) + \Omega^2,$$ $$k_1 = -\lambda$$ и определяет проходимый дважды луч с началом в $(k_0, k_1) = (-\Omega^2, -\lambda)$ и направлением вдоль положительного направления оси $k_0$.

Примеры построения контурных и тепловых карт для максимальной действительной части корня полинома $Q(p) = p^2 + a p + b$

Контурную карту с метками линий уровня можно построить с помощью функций contour и clabel.

Вместо меток линий уровня можно отобразить шкалу или построить соответствующую тепловую карту со шкалой с помощью функций imshow и colorbar.

Создание демонстрационного видео

Построение фазовых портретов для задания 22

Построение бифуркационной диаграммы для задания 22